// #include "include/LPA.h"

// void LPA::assign_flow(int id, int priority, bool move_from_unassign, bool is_scheduled) {
//     flows[id].priority     = priority;
//     flows[id].is_scheduled = is_scheduled;
//     assign_flow_set.insert(id);
//     if (move_from_unassign) {
//         unassign_flow_set.erase(id);
//     }
// }

// void LPA::run() {
//     int priority = flow_num;
//     unassign_flow_set.clear();
//     assign_flow_set.clear();
//     ep_flow_set.clear();
//     max_ep_source = max_ep_dest = max_lp_source = max_lp_dest = 0;
//     for (int i = 1; i <= flow_num; i++) {
//         unassign_flow_set.insert(i);
//         flows[i].is_scheduled = false;
//     }
//     // 按照关键性升序，相对截止时间降序，周期降序排序
//     // 排前面的优先级低（分配到的优先级数字大）
//     sort(flows + 1, flows + flow_num + 1, [&](flow& a, flow& b) {
//         if (a.critical == b.critical) {
//             if (a.relative_dl == b.relative_dl) {
//                 return a.period > b.period;
//             }
//             return a.relative_dl > b.relative_dl;
//         }
//         return a.critical < b.critical;
//     });
//     while (!unassign_flow_set.empty()) {
//         bool is_schedule = false;
//         int  schedule_id;
//         auto origin_max_ep_source = max_ep_source, origin_max_ep_dest = max_ep_dest;
//         for (auto cur_id : unassign_flow_set) {
//             max_ep_source = max(origin_max_ep_source, flows[cur_id].cw);
//             max_ep_dest   = max(origin_max_ep_dest, flows[cur_id].cr);
//             if (WCRT(flows[cur_id])) {
//                 assign_flow(cur_id, priority);
//                 is_schedule = true;
//                 schedule_id = cur_id;
//                 break;
//             }
//         }
//         if (!is_schedule) {
//             auto now = unassign_flow_set.begin();
//             ep_flow_set.insert(*now);
//             max_ep_source = max(origin_max_ep_source, flows[*now].cw);
//             max_ep_dest   = max(origin_max_ep_dest, flows[*now].cr);
//             unassign_flow_set.erase(now);
//         } else {
//             for (auto cur_id : ep_flow_set) {
//                 bool is_schedule = WCRT(flows[cur_id]);
//                 assign_flow(cur_id, priority, false, is_schedule);
//             }
//             for (auto cur_id : ep_flow_set) {
//                 max_lp_source = max(max_lp_source, flows[cur_id].cw);
//                 max_lp_dest   = max(max_lp_dest, flows[cur_id].cr);
//             }
//             max_lp_source = max(max_lp_source, flows[schedule_id].cw);
//             max_lp_dest   = max(max_lp_dest, flows[schedule_id].cr);
//             ep_flow_set.clear();
//             max_ep_dest = max_ep_source = 0;
//             priority--;
//         }
//     }

//     for (auto cur_id : ep_flow_set) {
//         bool is_schedule = WCRT(flows[cur_id]);
//         assign_flow(cur_id, priority, false, is_schedule);
//     }
//     LPR();
// }

// void LPA::LPR() {
//     sort(flows + 1, flows + flow_num + 1, [&](flow& a, flow& b) {
//         if (a.priority == b.priority) {
//             return a.is_scheduled > b.is_scheduled;
//         }
//         return a.priority < b.priority;
//     });
//     queue_load.assign(flow_num + 1, 0);
//     int j = flows[1].priority - 1;
//     for (int i = 1; i <= flow_num; i++) {
//         // if (flows[i].priority != flows[i - 1].priority || flows[i].is_scheduled == false) {
//         if (flows[i].priority != flows[i - 1].priority) {
//             j++;
//         }
//         queue_load[j] += (HP / flows[i].period) * flows[i].size;
//         // INFO("flow_id: %d, j: %d , queue_load: %d\n", i, j, queue_load[j]);
//     }
//     average_load = accumulate(queue_load.begin(), queue_load.end(), 0) / NEW_PRIORITY_NUM;
//     // INFO("average_load: %d, j: %d\n", average_load, j);
//     min_cost  = __LONG_LONG_MAX__;
//     queue_num = flows[flow_num].priority - flows[1].priority + 1;
//     map_queue.resize(NEW_PRIORITY_NUM);
//     for (auto& q : map_queue) {
//         q.clear();
//     }
//     Reassign_priority(flows[1].priority, 0, 0);
// }

// void LPA::Reassign_priority(int old_prio, int cur_lpa_prio, u64 cost) {
//     // Logger::log(LOG_PATH, "old_prio: %d, cur_lpa_prio: %d, cost: %llu, min: %llu\n", old_prio, cur_lpa_prio, cost,
//     // min_cost);
//     if (cost >= min_cost) {
//         return;
//     }
//     if (old_prio == flows[flow_num].priority + 1) {
//         while (cur_lpa_prio < NEW_PRIORITY_NUM) {
//             cost += average_load * average_load;
//             cur_lpa_prio++;
//         }
//         if (cost < min_cost) {
//             min_cost = cost;
//             for (int j = 1; j <= flow_num; j++) {
//                 flows[j].new_priority = 0;
//             }
//             int j = 1;
//             for (int i = 0; i < NEW_PRIORITY_NUM; i++) {
//                 for (auto& prio : map_queue[i]) {
//                     while (j <= flow_num && flows[j].priority == prio) {
//                         flows[j].new_priority = i + 1;
//                         j++;
//                     }
//                 }
//             }
//         }
//         return;
//     }
//     if (cur_lpa_prio == NEW_PRIORITY_NUM) {
//         return;
//     }
//     u64 cur_load = 0;
//     while (cur_load <= average_load && old_prio <= flows[flow_num].priority) {
//         cur_load += queue_load[old_prio];
//         map_queue[cur_lpa_prio].push_back(old_prio);
//         old_prio++;
//         Logger::log(LOG_PATH,
//                     "cur_load: %llu, average_load: %llu, old_prio: %d, cur_lpa_prio: %d, cost: %llu, min:%llu\n ",
//                     cur_load, average_load, old_prio, cur_lpa_prio,
//                     cost + (cur_load - average_load) * (cur_load - average_load), min_cost);
//         Reassign_priority(old_prio, cur_lpa_prio + 1, cost + (cur_load - average_load) * (cur_load - average_load));
//     }
//     map_queue[cur_lpa_prio].clear();
// }

// void LPA::debug_flows() {
//     static flow temp[FLOW_MAX_NUM];
//     for (int i = 1; i <= flow_num; i++) {
//         temp[i] = flows[i];
//     }
//     sort(temp + 1, temp + flow_num + 1, [&](flow& a, flow& b) { return a.id < b.id; });
//     printf("flow_id  priority  new_priority  is_scheduled   wcrt\n");
//     for (int i = 1; i <= flow_num; i++) {
//         printf("%3d %10d %10d %13d %13.2f\n", i, temp[i].priority, temp[i].new_priority, temp[i].is_scheduled,
//                temp[i].wcrt);
//     }

//     std::ofstream out(RESULT_CSV_PATH);
//     if (!out.is_open()) {
//         std::cerr << "Failed to open file: " << RESULT_CSV_PATH << std::endl;
//         return;
//     }

//     // 写 CSV 表头
//     out << "flow_id,is_scheduled,priority,lpa_priority,wcrt\n";

//     // 从 1 开始（仿照原始代码）
//     for (size_t i = 1; i <= flow_num; ++i) {
//         out << i << "," << temp[i].is_scheduled << "," << temp[i].priority << "," << temp[i].new_priority << ","
//             << std::fixed << std::setprecision(2) << temp[i].wcrt << "\n";
//     }

//     out.close();
// }